package distributed.controller;

import java.util.Hashtable;

import org.w3c.dom.Node;

import distributed.LogWriter;

import server.ClientState;
import server.IProtocolHandler;

import xml.Message;


/**
 * An implementation of IProtocolHandler that takes a ClientState and a Message and passes them
 * to the correct controller.
 */
public class DLSProtocolFactory implements IProtocolHandler{
	/** The single instance of this class */
	static DLSProtocolFactory instance;
	
	private DLSProtocolFactory(){}
	
	/** A method to retrieve the singleton of this class */
	public static DLSProtocolFactory getInstance() {
		if (instance == null)
			instance = new DLSProtocolFactory();
		return instance;
	}
	
	/** A hash table containing an association between the request types and their associated 
	 * controllers */
	static Hashtable<String, IProtocolController> controllers =
			new Hashtable<String, IProtocolController>();
	
	static {
		controllers.put("addChoiceRequest", new AddChoiceController());
		controllers.put("addEdgeRequest", new AddEdgeController());
		controllers.put("adminRequest", new AdminLoginController());
		controllers.put("closeRequest", new CloseEventController());
		controllers.put("createRequest", new CreateEventController());
		controllers.put("forceRequest", new ForceCloseController());
		controllers.put("removeRequest", new RemoveEventController());
		controllers.put("reportRequest", new RequestReportController());
		controllers.put("signInRequest", new EventSignInController());
		controllers.put("chatRequest", new ChatController());
	}
	
	public synchronized Message process (ClientState st, Message request) {
		//Terrible lazy inefficient function to trim out all the nonsense
		String clipXML = request.toString().replaceAll("(?s)<!--.*?-->", "")
											.replaceAll(">[^<>]*<", "><");
		if (clipXML.contains("chatRequest") && clipXML.contains("</text>")) {
			String chat = request.toString();
			chat = chat.substring(chat.indexOf("<text>"), chat.indexOf("</text>")+7);
			clipXML = clipXML.replace("<text></text>", chat);
		}
		request = new Message(clipXML);
		
		Node child = request.contents.getFirstChild(); //Get the request type from the message
		
		String type = child.getLocalName(); //Get its name
		
		LogWriter.writeToLog(request); //Lets log this
		
		IProtocolController control = controllers.get(type); //Yoink the controller from storage
		
		if (control != null) { // If it exists...
			Message respond = control.newCopy().process(st, request); //Copy the controller and process
			LogWriter.writeToLog(respond); //Log the output
			return respond; //Send it off
		}
		
		// unknown? no idea what to do
		System.err.println("Unable to handle message:" + request);
		return null;
	}
	
}
